home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C25 / Recycle2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  3.2 KB  |  137 lines

  1. //: C25:Recycle2.cpp
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // Adding a factory method
  7. #include "sumValue.h"
  8. #include "../purge.h"
  9. #include <fstream>
  10. #include <vector>
  11. #include <typeinfo>
  12. #include <cstdlib>
  13. #include <ctime>
  14. using namespace std;
  15. ofstream out("Recycle2.out");
  16.  
  17. class Trash {
  18.   double _weight;
  19.   void operator=(const Trash&);
  20.   Trash(const Trash&);
  21. public:
  22.   Trash(double wt) : _weight(wt) { }
  23.   virtual double value() const = 0;
  24.   double weight() const { return _weight; }
  25.   virtual ~Trash() {}
  26.   // Nested class because it's tightly coupled
  27.   // to Trash:
  28.   class Info {
  29.     int type;
  30.     // Must change this to add another type:
  31.     static const int maxnum = 3;
  32.     double data;
  33.     friend class Trash;
  34.   public:
  35.     Info(int typeNum, double dat)
  36.       : type(typeNum % maxnum), data(dat) {}
  37.   };
  38.   static Trash* factory(const Info& info);
  39. };
  40.  
  41. class Aluminum : public Trash {
  42.   static double val;
  43. public:
  44.   Aluminum(double wt) : Trash(wt) {}
  45.   double value() const { return val; }
  46.   static void value(double newval) {
  47.     val = newval;
  48.   }
  49.   ~Aluminum() { out << "~Aluminum\n"; }
  50. };
  51.  
  52. double Aluminum::val = 1.67F;
  53.  
  54. class Paper : public Trash {
  55.   static double val;
  56. public:
  57.   Paper(double wt) : Trash(wt) {}
  58.   double value() const { return val; }
  59.   static void value(double newval) {
  60.     val = newval;
  61.   }
  62.   ~Paper() { out << "~Paper\n"; }
  63. };
  64.  
  65. double Paper::val = 0.10F;
  66.  
  67. class Glass : public Trash {
  68.   static double val;
  69. public:
  70.   Glass(double wt) : Trash(wt) {}
  71.   double value() const { return val; }
  72.   static void value(double newval) {
  73.     val = newval;
  74.   }
  75.   ~Glass() { out << "~Glass\n"; }
  76. };
  77.  
  78. double Glass::val = 0.23F;
  79.  
  80. // Definition of the factory method. It must know
  81. // all the types, so is defined after all the
  82. // subtypes are defined:
  83. Trash* Trash::factory(const Info& info) {
  84.   switch(info.type) {
  85.     default: // In case of overrun
  86.     case 0:
  87.       return new Aluminum(info.data);
  88.     case 1:
  89.       return new Paper(info.data);
  90.     case 2:
  91.       return new Glass(info.data);
  92.   }
  93. }
  94.  
  95. // Generator for Info objects:
  96. class InfoGen {
  97.   int typeQuantity;
  98.   int maxWeight;
  99. public:
  100.   InfoGen(int typeQuant, int maxWt)
  101.     : typeQuantity(typeQuant), maxWeight(maxWt) {
  102.     srand(time(0)); 
  103.   }
  104.   Trash::Info operator()() {
  105.     return Trash::Info(rand() % typeQuantity, 
  106.       static_cast<double>(rand() % maxWeight));
  107.   }
  108. };
  109.  
  110. int main() {
  111.   vector<Trash*> bin;
  112.   // Fill up the Trash bin:
  113.   InfoGen infoGen(3, 100);
  114.   for(int i = 0; i < 30; i++)
  115.     bin.push_back(Trash::factory(infoGen()));
  116.   vector<Aluminum*> alBin;
  117.   vector<Paper*> paperBin;
  118.   vector<Glass*> glassBin;
  119.   vector<Trash*>::iterator sorter = bin.begin();
  120.   // Sort the Trash:
  121.   while(sorter != bin.end()) {
  122.     Aluminum* ap = 
  123.       dynamic_cast<Aluminum*>(*sorter);
  124.     Paper* pp = dynamic_cast<Paper*>(*sorter);
  125.     Glass* gp = dynamic_cast<Glass*>(*sorter);
  126.     if(ap) alBin.push_back(ap);
  127.     if(pp) paperBin.push_back(pp);
  128.     if(gp) glassBin.push_back(gp);
  129.     sorter++;
  130.   }
  131.   sumValue(alBin);
  132.   sumValue(paperBin);
  133.   sumValue(glassBin);
  134.   sumValue(bin);
  135.   purge(bin); // Cleanup
  136. } ///:~
  137.